#pragma once

#include <iostream>
#include <string>
#include <functional>
#include <future>
#include <chrono>

using namespace std;

#define     TEST_FUTUREANDPROMISE               1

/**
 *          使用 std::promise和std::future结合使用，对不同线程间异步操作
 */
namespace FutureAndPromise
{
    class Object
    {
        public:
        Object(int num=0, const string &str=string())
        {
            m_num = num;
            m_str = str;
        }
        ~Object(){}
        int m_num = 0 ;
        string m_str;        
    };
};

void asyncTask(std::promise<int> &promiseObj)
{
    std::this_thread::sleep_for(std::chrono::seconds(2));

    promiseObj.set_value(88);
}

void threadFuncA(std::promise<int> &p)
{
    std::cout << "threadFuncA" << endl;
    std::this_thread::sleep_for(std::chrono::seconds(2));

    p.set_value(88);
    std::cout << "Finish threadFuncA" << endl;
}

void threadFuncB(std::future<int> &f)
{
    std::cout << "threadFuncB" << endl;
    // 阻塞函数, 直到收到相关联的std::promise对象传入的数据
    auto val = f.get();
    std::cout << "Finish threadFuncB - val: " << val << endl;
}

void threadFuncC(std::promise<FutureAndPromise::Object> &pro)
{
    std::this_thread::sleep_for(std::chrono::seconds(2));

    // 设置值
    pro.set_value(FutureAndPromise::Object(8,"88"));
}

void threadFuncD(std::future<FutureAndPromise::Object> &fu)
{
    auto val = fu.get();
    std::cout << "val.num: " << val.m_num << " | str: " << val.m_str << endl;
}
